//1、 ! 非空断言操作符
type numberF = () => number;
const f = (val:numberF|null):number => {
  return val!();
}


//2、?. 可选链运算符
let aa:any,customMethod:any;
const val = aa?.b;
//编译成：var val = aa === null || aa === void 0 ? void 0 : aa.b;
let result = customMethod?.();
// 编译成：var result = customMethod === null || customMethod === void 0 ? void 0 : customMethod();


// 3、?? 空值合并运算符（与逻辑或 || 运算符不同，逻辑或会在左操作数为 falsy 值时返回右侧操作数。也就是说，如果你使用 || 来为某些变量设置默认的值时，你可能会遇到意料之外的行为。比如为 falsy 值（''、NaN 或 0）时）
const foo = null ?? 'default string';
console.log(foo); // 输出："default string"
const baz = 0 ?? 42;
console.log(baz); // 输出：0

// 4、 TS内置工具类型
  // 4.1 Partial<T> 将某个接口类型的属性，变为可选即 ?:
  interface testPartialPre {
    name: string,
    age: number
  }
  type TestPartial = Partial<testPartialPre>;
  const obj1:TestPartial = {};

  //4.2 Required<T> 将某个接口类型的属性，全变为必选。与Partial 相反
  type TestRequired = Required<TestPartial>
  const obj3:TestRequired = {
    name: '',
    age: 18
  }


// 5、& 运算符，通过 & 运算符可以将现有的多种类型叠加到一起成为一种类型，它包含了所需的所有类型的特性。“且”的意思
interface I1 {
  name: string
}
type I2 = {
  age: number;
}
type I3 = I1 & I2;
const obj4:I3 = {
  name: '',
  age: 18
}

//6、| 分隔符，表示取值可以为多种类型中的一种，联合类型使用 | 分隔每个类型。“或” 的意思
// 例子1：
const obj6:number|string = ''
//例子2：
type I4 = I1 | I2;
const obj7:I4 = {
  name: ''
}
